package com.yizisu.library.login.impl


import android.content.Intent
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.Scopes
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.Scope
import com.google.android.gms.tasks.Task
import com.weilele.mvvm.app
import com.yizisu.library.login.BaseGameLogin
import com.yizisu.library.login.IGameLogin
import com.yizisu.login.R

internal class GameLoginGoogleImpl(fm: FragmentManager, lifecycleOwner: LifecycleOwner) :
        BaseGameLogin(fm, lifecycleOwner) {
    companion object {
        private const val RC_SIGN_IN = 901

        internal fun lastLoginUserInfo(): IGameLogin.UserInfo? {
            //判断google是否登录
            val account = GoogleSignIn.getLastSignedInAccount(app)
            return if (account != null && account.idToken != null && account.id != null) {
                toUserInfo(account)
            } else {
                null
            }
        }

        private fun toUserInfo(account: GoogleSignInAccount): IGameLogin.UserInfo {
            val personName = account.displayName
            val personGivenName = account.givenName
            val personFamilyName = account.familyName
            val personEmail = account.email
            val personId = account.id
            val personPhoto = account.photoUrl.toString()
            return IGameLogin.UserInfo(
                    account.id!!,
                    account.idToken!!,
                    IGameLogin.LOGIN_GOOGLE,
                    personName,
                    personPhoto
            )
        }

        internal fun logout() {
            GoogleSignIn.getClient(app, createGso()).signOut()
        }

        private fun createGso(): GoogleSignInOptions {
            val serverClientId = app.getString(R.string.server_client_id)
            return GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestScopes(Scope(Scopes.DRIVE_APPFOLDER))
                    .requestServerAuthCode(serverClientId)
                    .requestIdToken(serverClientId)
                    .requestEmail()
                    .build()
        }
    }

    private val gso by lazy { createGso() }

    private val mGoogleSignInClient = GoogleSignIn.getClient(app, gso)


    override fun startLogin() {
        val signInIntent = mGoogleSignInClient.signInIntent
        callFragment.startActivityForResult(signInIntent, RC_SIGN_IN)
    }

    override fun logOut() {
        logout()
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>?) {
        try {
            val account = completedTask?.getResult(ApiException::class.java)
            if (account?.idToken == null) {
                loginCancel()
            } else {
                loginSuccess(account)
            }
        } catch (e: ApiException) {
            e.printStackTrace()
            loginFail(e)
        }
    }

    private fun loginCancel() {
        listeners.forEach {
            it.onCancel(IGameLogin.LOGIN_GOOGLE)
        }
    }

    private fun loginFail(error: Throwable) {
        listeners.forEach {
            it.onError(error, IGameLogin.LOGIN_GOOGLE)
        }
    }

    private fun loginSuccess(account: GoogleSignInAccount) {
        val info = toUserInfo(account)
        listeners.forEach {
            it.onSuccess(info, IGameLogin.LOGIN_GOOGLE)
        }
    }

    override fun onActivityResultByFragment(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            handleSignInResult(task)
        }
    }
}